package com.shop.cereshop.commons.tencent.moderation.service.impl;

import com.shop.cereshop.commons.tencent.moderation.cache.ModerationCacheManager;
import com.shop.cereshop.commons.tencent.moderation.config.TencentModerationConfig;
import com.shop.cereshop.commons.tencent.moderation.domain.request.TextModerationParam;
import com.shop.cereshop.commons.tencent.moderation.domain.response.ModerationResult;
import com.shop.cereshop.commons.tencent.moderation.service.TextModerationService;
import com.shop.cereshop.commons.tencent.moderation.util.HashUtils;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.tms.v20201229.TmsClient;
import com.tencentcloudapi.tms.v20201229.models.TextModerationRequest;
import com.tencentcloudapi.tms.v20201229.models.TextModerationResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @description:
 * @author zdd
 * @date 2025/10/26 15:20
 * @version 1.0
 */
@Slf4j
@Service
public class TextModerationServiceImpl implements TextModerationService {

    @Autowired
    private TencentModerationConfig config;

    @Autowired
    private ModerationCacheManager cacheManager;

    @Override
    @Retryable(value = TencentCloudSDKException.class,
            maxAttempts = 3,
            backoff = @Backoff(delay = 1000, multiplier = 2))
    public ModerationResult moderateText(TextModerationParam param) {
        long startTime = System.currentTimeMillis();

        try {
            // 检查缓存
            String cacheKey = HashUtils.md5(param.getContent());
            ModerationResult cachedResult = cacheManager.getTextResult(cacheKey);
            if (cachedResult != null) {
                cachedResult.setCostTime(System.currentTimeMillis() - startTime);
                log.info("文本审核缓存命中, content: {}, 耗时: {}ms", param.getContent(), cachedResult.getCostTime());
                return cachedResult;
            }

            // 调用腾讯云API核心审核逻辑
            ModerationResult result = doSingleModerateText(param);

            // 缓存结果
            cacheManager.putTextResult(cacheKey, result);

            log.info("文本审核完成, suggestion: {}, label: {}, score: {}, 耗时: {}ms",
                    result.getSuggestion(), result.getLabel(), result.getScore(), result.getCostTime());

            return result;

        } catch (Exception e) {
            log.error("文本审核失败, contentLength: {}, error: {}",
                    param.getContent().length(), e.getMessage(), e);
            return ModerationResult.fail("文本审核服务异常: " + e.getMessage())
                    .setCostTime(System.currentTimeMillis() - startTime);
        }
    }

    /**
     * 单个审核（内部方法，不包含缓存逻辑）
     */
    private ModerationResult doSingleModerateText(TextModerationParam param) {
        long startTime = System.currentTimeMillis();
        try {
            // 调用腾讯云API
            TmsClient client = createTmsClient();
            TextModerationRequest tmsRequest = new TextModerationRequest();
            tmsRequest.setContent(HashUtils.toBase64(param.getContent()));
            tmsRequest.setBizType(StringUtils.isNotBlank(param.getBizType()) ? param.getBizType()
                    : config.getModeration().getText().getBizType());
            tmsRequest.setDataId(StringUtils.isNotBlank(param.getDataId()) ? param.getDataId() : UUID.randomUUID().toString());

            TextModerationResponse response = client.TextModeration(tmsRequest);
            // log.info("单个文本审核, request: {}, response: {}", JSON.toJSONString(tmsRequest), JSON.toJSONString(response));

            ModerationResult result = ModerationResult.success(response.getSuggestion(), response.getLabel(), response.getScore());
            return result.setModerationType("TEXT")
                    .setCostTime(System.currentTimeMillis() - startTime)
                    .setDataId(tmsRequest.getDataId())
                    .setBizType(tmsRequest.getBizType())
                    .setModerationTime(System.currentTimeMillis());

        } catch (TencentCloudSDKException e) {
            log.error("单个文本审核失败, error: {}", e.getMessage(), e);
            return ModerationResult.fail("文本审核服务异常: " + e.getMessage());
        }
    }

    /**
     * 批量文本审核（优化版）
     */
    @Override
    public List<ModerationResult> batchModerateText(List<TextModerationParam> params) {
        long startTime = System.currentTimeMillis();

        try {
            // 1. 生成所有内容的哈希值
            Map<String, TextModerationParam> hashToRequest = params.stream()
                    .collect(Collectors.toMap(
                            param -> HashUtils.md5(param.getContent()),
                            param -> param
                    ));

            // 2. 批量查询缓存
            Map<String, ModerationResult> cachedResults = cacheManager.batchGetTextResults(
                    new ArrayList<>(hashToRequest.keySet())
            );

            // 3. 找出需要实际审核的内容
            List<TextModerationParam> toModerate = new ArrayList<>();
            Map<String, ModerationResult> finalResults = new HashMap<>();

            for (Map.Entry<String, TextModerationParam> entry : hashToRequest.entrySet()) {
                String hash = entry.getKey();
                TextModerationParam request = entry.getValue();
                ModerationResult cachedResult = cachedResults.get(hash);

                if (cachedResult != null) {
                    // 使用缓存结果
                    finalResults.put(hash, cachedResult);
                } else {
                    // 需要实际审核
                    toModerate.add(request);
                }
            }

            // 4. 批量审核未缓存的内容
            if (!toModerate.isEmpty()) {
                Map<String, ModerationResult> newResults = toModerate.parallelStream()
                        .collect(Collectors.toMap(
                                request -> HashUtils.md5(request.getContent()),
                                this::doSingleModerateText
                        ));

                // 批量存储新结果到缓存
                cacheManager.batchPutTextResults(newResults);

                // 合并结果
                finalResults.putAll(newResults);
            }

            // 5. 按原始顺序返回结果
            return params.stream()
                    .map(param -> finalResults.get(HashUtils.md5(param.getContent())))
                    .collect(Collectors.toList());

        } catch (Exception e) {
            log.error("批量文本审核失败, count: {}, error: {}", params.size(), e.getMessage(), e);
            // 降级为逐个审核
            return params.stream()
                    .map(this::moderateText)
                    .collect(Collectors.toList());
        } finally {
            log.info("批量文本审核完成, total: {}, cost: {}ms",
                    params.size(), System.currentTimeMillis() - startTime);
        }
    }



    @Async("moderationExecutor")
    @Override
    public CompletableFuture<ModerationResult> moderateTextAsync(TextModerationParam request) {
        return CompletableFuture.completedFuture(moderateText(request));
    }

    private TmsClient createTmsClient() {
        Credential cred = new Credential(config.getSecretId(), config.getSecretKey());
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("tms.tencentcloudapi.com");
        httpProfile.setConnTimeout(config.getModeration().getText().getTimeout());

        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);

        return new TmsClient(cred, config.getRegion(), clientProfile);
    }

}
